#include "lcd1602.h"

void vDelayus(int nus)
{
	int i = 0;
	while(nus--)
	for(i = 0; i < 12; i++)
	{

	}
}

void vDelayms(int nms)
{
	int i = 0;
	while(nms--)
	for(i = 0; i < 12000; i++)
	{
		
	}
}


void vLcd_GPIO_Init(void)
{
    GPIO_InitTypeDef LCD_init_struct;
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    LCD_init_struct .GPIO_Mode = GPIO_Mode_Out_PP;
    LCD_init_struct .GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_8|
                                GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12|	
                                GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15  ;													
    LCD_init_struct .GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&LCD_init_struct);
}



void vLCD_BusyTest(void)
{
	while( (GPIOB ->ODR & 0X8000) != 0);
}



void vLcd_Write(int iData, int iType)
{
	//将数据写入数据端口
	LCD_GPIO->ODR &= 0x00FF;  
  	LCD_GPIO->ODR |= (iData << 8);

	GPIO_ResetBits(LCD_GPIO, LCD_PIN_RW);   //写模式
	//选择数据指令模式
    if(iType == COMMAND)
        GPIO_ResetBits(LCD_GPIO, LCD_PIN_RS);
    if(iType == DATA)
        GPIO_SetBits(LCD_GPIO, LCD_PIN_RS);
	vDelayus(70);   
	GPIO_SetBits(LCD_GPIO, LCD_PIN_EN);//使能写入
	vDelayus(3000); 
	GPIO_ResetBits(LCD_GPIO, LCD_PIN_EN);//关闭写入
	vDelayus(100);  
}


void vLcd1602_Init(void)
{
	vDelayms(15);
	vLcd_Write(0x38, COMMAND);
	vDelayms(5);
	vLcd_Write(0x38, COMMAND);
	vDelayms(5);
	vLcd_Write(0x38, COMMAND);//16*2，5*7，8位数据接口
	vLCD_BusyTest();
	vLcd_Write(0x0f, COMMAND);//开显示，显示光标，光标闪烁
	vLCD_BusyTest();
	vLcd_Write(0x06, COMMAND);//显示后光标自动加一，不移屏
}

void vDisplay_Clear(void)
{
	vLCD_BusyTest();
	vLcd_Write(0x01, COMMAND);
	vLCD_BusyTest();
	vLcd_Write(0x02, COMMAND);
}


void vPos(int x, int y)
{
	int Itemp = 0x80;
	if(y == 0)
		Itemp = Itemp + 0x00 + x;
	if(y == 1)
		Itemp = Itemp + 0x40 + x;
	vLCD_BusyTest();
	vLcd_Write(Itemp, COMMAND);
	LCD_GPIO->ODR &= 0x00FF;
}


void vDisplay_Char(int x, int y, char cTemp)
{
	vPos(x, y);
	vLCD_BusyTest();
	vLcd_Write((int)cTemp, DATA);
}


void vDisplay_string(int x, int y, char *s)
{
	int i = 0;
	vPos(x, y);
	while(s[i] != 0)
	{
		vLcd_Write((int)s[i], DATA);
		 i++;
		vDelayms(10);
	}
}


void vDisplay_floatnum(int x, int y, float num)
{
	int a[15] = {0};
	int i = 0;
	int b = num > 0 ? num*100 : (-num)*100;
	if(num == 0)
	{
		vPos(x, y);
		vLCD_BusyTest();
		vLcd_Write(0 + 48, DATA);
		return;
	}

	while(b)
	{
		a[i] = b % 10;
		b = b / 10;
		i++;
		if(i > 14)
		{
			vDisplay_string(0, 0, "input err !");
			return;
		}
	}
	
	if(num < 0)
	vDisplay_Char( x,  y,'-');
	i = i - 1;
	while(i >= 0)
	{
		vLCD_BusyTest();
		vLcd_Write(a[i] + 48, DATA);
		i--;
		if(i == 1)
		{
		vLCD_BusyTest();
		vLcd_Write('.', DATA);
		}
	}
}